import java.util.ArrayList;

public class Board {
	private static int BOARD_SIZE = 10;
	private colorCode[][] squares;
	private colorCode currentPlayer;

	public Board() {
		squares = new colorCode[BOARD_SIZE][BOARD_SIZE];
	}

	public Board(Board b) {
		//squares = (b.squares).clone();
		squares = new colorCode[BOARD_SIZE][BOARD_SIZE];
		for (int i = 0; i < BOARD_SIZE; i++) {
			for (int j = 0; j < BOARD_SIZE; j++) {
				squares[i][j] = b.squares[i][j];
			}
		}

		currentPlayer = b.currentPlayer;
	}

	public void InitBoard() {
		for (int i = 0; i < BOARD_SIZE; i++) {
			for (int j = 0; j < BOARD_SIZE; j++) {
				squares[i][j] = colorCode.EMPTY;
			}
		}

		squares[(BOARD_SIZE / 2) - 1][(BOARD_SIZE / 2) - 1] = colorCode.WHITE;
		squares[(BOARD_SIZE / 2)][(BOARD_SIZE / 2)] = colorCode.WHITE;
		squares[(BOARD_SIZE / 2) - 1][(BOARD_SIZE / 2)] = colorCode.BLACK;
		squares[(BOARD_SIZE / 2)][(BOARD_SIZE / 2) - 1] = colorCode.BLACK;

		currentPlayer = colorCode.WHITE;
	}

	public ArrayList<Move> getPossibleMoves() {
		ArrayList<Move> result = new ArrayList<Move>();

		for (int i = 0; i < BOARD_SIZE; i++) {
			for (int j = 0; j < BOARD_SIZE; j++) {
				if (squares[i][j] == colorCode.EMPTY) {
					if(hasNeighbour(i,j)){
						result.add(new Move(i, j));
					}
				}
			}
		}

		return result;
	}

	private boolean hasNeighbour(int i, int j) {
		boolean result = false;
		if((i-1)>0 && (j-1)>0)  		{result |= ( squares[i-1][j-1] != colorCode.EMPTY );} 
		if((i)>0 && (j-1)>0)  			{result |= ( squares[i][j-1] != colorCode.EMPTY );}
		if((i+1)<BOARD_SIZE && (j-1)>0) {result |= ( squares[i+1][j-1] != colorCode.EMPTY );}
		if((i-1)>0 && (j)>0)  			{result |= ( squares[i-1][j] != colorCode.EMPTY );}
		if((i+1)<BOARD_SIZE && (j)>0)  	{result |= ( squares[i+1][j] != colorCode.EMPTY );}
		if((i-1)>0 && (j+1)<BOARD_SIZE) {result |= ( squares[i-1][j+1] != colorCode.EMPTY );}
		if((i)>0 && (j+1)<BOARD_SIZE)  	{result |= ( squares[i][j+1] != colorCode.EMPTY );}
		if((i+1)<BOARD_SIZE && (j+1)<BOARD_SIZE) {result |= ( squares[i+1][j+1] != colorCode.EMPTY );}
			
		return result;
	}

	public int getScore(colorCode player) {
		int result = 0;
		for (int i = 0; i < BOARD_SIZE; i++) {
			for (int j = 0; j < BOARD_SIZE; j++) {
				if(squares[i][j] == player){
					result++ ;
				}
			}
		}
		return result;
	}
	
	public Double getEval(colorCode player) {
		Double result = 0.0;
		Double center = 0.5*BOARD_SIZE;
		Double temp_score;
		for (int i = 0; i < BOARD_SIZE; i++) {
			for (int j = 0; j < BOARD_SIZE; j++) {
				temp_score = Math.abs(i-center) + Math.abs(j-center);
				if (squares[i][j] == player) {
					result += temp_score;
				} else if (squares[i][j] != colorCode.EMPTY) {
					result -= temp_score;
				}
				
			}
		}
		return result;
	}

	public boolean isFull() {
		for (int i = 0; i < BOARD_SIZE; i++) {
			for (int j = 0; j < BOARD_SIZE; j++) {
				if (squares[i][j] == colorCode.EMPTY) {
					return false;
				}
			}
		}
		return true;
	}

	public colorCode getCurrentPlayer() {
		return currentPlayer;
	}

	public void Display() {
				System.out.print("SCORE: W=");
		System.out.print(getScore(colorCode.WHITE));
		System.out.print(" B=");
		System.out.println(getScore(colorCode.BLACK));
		if(currentPlayer == colorCode.WHITE){
			System.out.println("trait aux blancs");
		} else {
			System.out.println("trait aux noirs");
		}
		System.out.print("+");
		for (int i = 0; i < BOARD_SIZE; i++) {
			System.out.print("--");
		}
		System.out.println("+");

		for (int i = 0; i < BOARD_SIZE; i++) {
			System.out.print("|");
			for (int j = 0; j < BOARD_SIZE; j++) {
				switch (squares[i][j]) {
				case WHITE:
					System.out.print("()");
					break;
				case BLACK:
					System.out.print("[]");
					break;
				default:
					System.out.print("  ");
					break;
				}
			}
			System.out.println("|");
		}
		System.out.print("+");
		for (int i = 0; i < BOARD_SIZE; i++) {
			System.out.print("--");
		}
		System.out.println("+");
	}

	public void Play(Move move) {
		// TODO Auto-generated method stub
		squares[move.x][move.y] = currentPlayer;

		Update(move.x, move.y, 1, 0);
		Update(move.x, move.y, 1, -1);
		Update(move.x, move.y, 0, -1);
		Update(move.x, move.y, -1, -1);
		Update(move.x, move.y, -1, 0);
		Update(move.x, move.y, -1, 1);
		Update(move.x, move.y, 1, 1);
		Update(move.x, move.y, 0, 1);

		if (currentPlayer == colorCode.WHITE) {
			currentPlayer = colorCode.BLACK;
		} else {
			currentPlayer = colorCode.WHITE;
		}
	}

	private void Update(int x, int y, int step_x, int step_y) {
		// TODO Auto-generated method stub

		int i = x + step_x;
		int j = y + step_y;
		int count = 0;
		while (i > 0 && i < BOARD_SIZE && j > 0 && j < BOARD_SIZE
				&& squares[i][j] != this.getCurrentPlayer()
				&& squares[i][j] != colorCode.EMPTY) {
			i += step_x;
			j += step_y;
			count++;
		}
		if (i > 0 && i < BOARD_SIZE && j > 0 && j < BOARD_SIZE) {
			if (squares[i][j] != this.getCurrentPlayer()) {
				count = 0;
			}
		}

		i = x;
		j = y;
		int k = 0;
		while (i > 0 && i < BOARD_SIZE && j > 0 && j < BOARD_SIZE && k < count) {
			i += step_x;
			j += step_y;
			squares[i][j] = this.getCurrentPlayer();
			k++;
		}

	}

}
